Appium is an open-source automation framework used for testing applications. It allows you to write automated tests for UI interactions, such as button clicks, text input, and screen navigation.
The key difference from Headless testing is that Appium uses OS Automation and creates a real window, moving a real mouse pointer to click the button or input the text.
|
While OS Automation approach uses the actual real application in tests, it is hard to recommend due to difficulties with setup and running on multiple platforms. It’s recommended to always use Headless testing except for test cases when you need to test OS features on the app. |
In this sample, we will create a simple calculator built using Avalonia. It follows the MVVM pattern, where the MainWindowViewModel
acts as the intermediary between the MainWindow
view and the underlying model (in this case, the arithmetic operations and the result).
The CommunityToolkit.Mvvm
library is used for the MVVM implementation, but ReactiveUI
or any other MVVM library can be used as well.
We will not go through creating this project step by step, but here are some important details from each file:
-
TestableApp.csproj
Project is generated from the Avalonia templates with a single major change needed for the automated testing:
<ItemGroup> <InternalsVisibleTo Include="TestableApp.Headless.XUnit" /> </ItemGroup>
This is needed in order to make controls marked with Name attribute visible in the tests project. But it can be avoided, if you use window.Find<Button>("ButtonName") method instead directly from the tests.
-
Program.cs, App.axaml, App.axaml.cs
Default entry point and App definitions generated from the template. No additional changes required in order to make app testable.
-
MainWindow.axaml, MainWindow.axaml.cs
The window contains two text boxes for user input, four buttons for arithmetic operations, and a text block to display the result. The buttons are bound to commands in the MainWindowViewModel. Important: all control that we want to have access to have Name attribute on them. This allows to programmatically click button or read text fro the text block.
-
MainWindowViewModel.cs
This file contains the view model for the MainWindow. The view model defines observable properties FirstOperand, SecondOperand, and Result, along with corresponding RelayCommand methods for the four arithmetic operations (Add, Subtract, Multiply, and Divide). When the user clicks one of the operation buttons, the respective command is executed, and the result is calculated and stored in the Result property.
To run Appium tests we will use XUnit:
dotnet new xunit
Next, add the following references:
-
Add the NuGet package reference Appium.WebDriver.
-
Add a project reference to the project we are going to test (TestableApp.csproj).
And to connect XUnit with Appium, we need to create a DefaultAppFixture that will be used in tests.
This fixture is responsible for initiating Appium and specifying where to find the executable of the app to run on each test.
In our sample, we will write simple test cases to validate that our application works correctly.
Start with creating a CalculatorTests.cs file.
And let’s add our first test:
[Fact]
public void Should_Add_Numbers()
{
// Arrange:
var firstOperandInput = _session.FindElementByAccessibilityId("FirstOperandInput")!;
var secondOperandInput = _session.FindElementByAccessibilityId("SecondOperandInput")!;
var addButton = _session.FindElementByAccessibilityId("AddButton")!;
var resultBox = _session.FindElementByAccessibilityId("ResultBox")!;
// Act:
firstOperandInput.Clear();
firstOperandInput.SendKeys("10");
secondOperandInput.Clear();
secondOperandInput.SendKeys("20");
addButton.Click();
// Assert:
Assert.Equal("30", resultBox.Text);
}
Important notes from this test:
-
Since we don’t have direct access to the view model or window object, we need to request all controls via FindElementByAccessibilityId.
-
Window is shared per test class, so input fields needs to be cleared before or after using them.
Before running Appium tests on Windows, WinAppDriver is required to be installed.
Please follow instructions from https://github.com/microsoft/WinAppDriver.
Now, to run these tests, we need: 1. Build the main application project. 2. Run WinAppDriver. 3. Run the tests in this project.
Nothing else is required on Windows, making it relatively simple.
Prerequisites:
-
Install Appium: https://appium.io/
-
Give Xcode helper the required permissions, see https://apple.stackexchange.com/questions/334008/xcode-helper-does-not-have-the-accessibility-permissions-needed-to-run-tests
-
Bundle TestableApp and install in your system
ℹ️this part is not documented in this samples project, as it gets pretty complicated from here. For help, please visit https://docs.avaloniaui.net/docs/distribution-publishing/macos -
Make sure that DefaultAppFixture has valid macOS app bundle ID to run
Running:
-
Run appium
-
Run the tests in this project
On each change in the application code, you would need to repackage and reinstall it.
Currently, Avalonia only supports OS Automation on Windows and macOS. However, you still can use Headless testing, which isn’t limited by any platform.
Any contributions related to Automation support in Avalonia are welcomed! Please visit https://github.com/AvaloniaUI/Avalonia or https://t.me/Avalonia if you want to help.